/**
 * @file 	 sq880.c
 * @brief       
 * @author 	 wenbo
 * @version  1.0
 * @date 	 2022-02-11
 * 
 * @copyright Copyright (c) 2022  YGL
 * 
 */

#include "sq880.h"
#include "stdlib.h"
#include "string.h"
#include "boardio.h"

#define _ABS(n)  (n < 0 ? (-n) : (n))
#define IS_VALID_PIN(id)    (id > 0 ? (true) : (false))
#define IS_SQ880_CHECK_OK(devId) (((devId) < g_sq880_listLen) && (g_sq880_list) && (g_sq880_list[(devId)].isInitOk))


//不同的项目需要在应用层配置好Type_sq880_Def列表然后传入初始化
/**************************************************************/
static uint8_t g_sq880_listLen = 0;
static Type_sq880_Def *g_sq880_list = NULL;
static const char str_mode[][10] = {"MODE_KEY", "MODE_IO", "MODE_485"};
static const char str_state[][10] = {"STA_NONE", "STA_FWD", "STA_REV", "STA_STOP", "STA_FAULT", "STA_OFF"};
static const char str_A_Src[][15] = {"A_SRC_KEY", "A_SRC_KNOB", "A_SRC_AI1", "A_SRC_HDI", "A_SRC_PLC", "A_SRC_STAGE", "A_SRC_PID", "A_SRC_MODBUS"};
/**************************************************************/


static int xp_sq880_debug(char *type,char *fun,char *param);

bool _xp_sq880_update_mode(Type_sq880_Def * const handle);
bool _xp_sq880_update_A_src(Type_sq880_Def * const handle);
bool _xp_sq880_set_mode(Type_sq880_Def * const handle, Type_sq880_Mode_Enum mode);
bool _xp_sq880_update_acc_time(Type_sq880_Def* const handle);
bool _xp_sq880_set_acc_time(Type_sq880_Def* const handle, uint16_t val);
bool _xp_sq880_update_dec_time(Type_sq880_Def* const handle);
bool _xp_sq880_set_dec_time(Type_sq880_Def* const handle, uint16_t val);
bool _xp_sq880_update_current(Type_sq880_Def * const handle);
bool _xp_sq880_update_state(Type_sq880_Def * const handle);
bool _xp_sq880_update_error_code(Type_sq880_Def * const handle);
bool _xp_sq880_set_io_default_function(Type_sq880_Def * const handle);
int xp_sq880_write_reginster(Type_sq880_Def * const handler, uint16_t addr, uint16_t *data, uint8_t len);
int xp_sq880_read_reginster(Type_sq880_Def * const handler, uint16_t addr, uint16_t read_len, uint8_t *rec_data, uint8_t *rec_len);

void memcpy_resv_word(void *des, void * const res, uint16_t size);
void xp_sq880_show(void);

//变频器列表
static Type_sq880_Def SQ880_list[] = {

    [0] = {
        
        .isReverseDir = false,

        .com = {
            .slave_id = 1,
            .port = 1,
            .speed = 9600,
        },

        .accTime = 10,
        .decTime = 10,

        .gpio_STF.boardId = 1,   .gpio_STF.pinId = 0,
        .gpio_STR.boardId = 1,   .gpio_STR.pinId = 1,
        .gpio_S0.boardId = 1,    .gpio_S0.pinId = 2,
        .gpio_S1.boardId = 1,    .gpio_S1.pinId = 3,
		.gpio_S2.boardId = 1,    .gpio_S2.pinId = 4,
    },
};

// sq880初始化
bool xp_sq880_init(Type_sq880_Def * const pList, uint8_t listLen)
{
	int ret = 0;

    if (NULL != pList && 0 != listLen){

        g_sq880_list = pList;
        g_sq880_listLen = listLen;

        for (uint8_t i = 0 ; i < g_sq880_listLen; i++){

            g_sq880_list[i].isInitOk = false;

            ret = xp_modbus_init(g_sq880_list[i].com.port, g_sq880_list[i].com.speed, MB_PAR_NONE, 100);

            if(0 != ret){
                println("sq880 <id:%d> modbus init fail ! ret = %d", g_sq880_list[i].com.slave_id, ret);
                return false;
            }else{
                bool isOK = false;

                /* 读取变频器运行模式 */
                isOK = _xp_sq880_update_mode(&g_sq880_list[i]);
                if (!isOK) { return false; }
                println("sq880 <id:%d> mode: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].mode < MODE_MAX ? (str_mode[g_sq880_list[i].mode]) : ("UNKNOW"));

                /* 读取变频器状态 */
                isOK = _xp_sq880_update_state(&g_sq880_list[i]);
                if (!isOK) { return false; }
                println("sq880 <id:%d> state: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].state < STA_MAX ? (str_state[g_sq880_list[i].state]) : ("UNKNOW"));

                /* 读取变频器A频率源 */
                isOK = _xp_sq880_update_A_src(&g_sq880_list[i]);
                if (!isOK) { return false; }
                println("sq880 <id:%d> A_src: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].A_src < A_SRC_MAX ? (str_A_Src[g_sq880_list[i].A_src]) : ("UNKNOW"));

                /* 设置变频器端子的默认功能(通用IO控制) */
                isOK = _xp_sq880_set_io_default_function(&g_sq880_list[i]);
                if (!isOK) { return false; }

                /* 设置或更新变频器加速时间 */
                if (0 != g_sq880_list[i].accTime){
                    isOK = _xp_sq880_set_acc_time(&g_sq880_list[i], g_sq880_list[i].accTime);
                    if (!isOK) { return false; }
                    println("sq880 <id:%d> set accTime: %.2fs", g_sq880_list[i].com.slave_id, g_sq880_list[i].accTime / 10.0f);
                }else{
                    isOK = _xp_sq880_update_acc_time(&g_sq880_list[i]);
                    if (!isOK) { return false; }
                    println("sq880 <id:%d> get accTime: %.2fs", g_sq880_list[i].com.slave_id, g_sq880_list[i].accTime / 10.0f);
                }

                /* 设置或更新变频器减速时间 */
                if (0 != g_sq880_list[i].accTime){
                    isOK = _xp_sq880_set_dec_time(&g_sq880_list[i], g_sq880_list[i].accTime);
                    if (!isOK) { return false; }
                    println("sq880 <id:%d> set decTime: %.2fs", g_sq880_list[i].com.slave_id, g_sq880_list[i].accTime / 10.0f);
                }else{
                    isOK = _xp_sq880_update_dec_time(&g_sq880_list[i]);
                    if (!isOK) { return false; }
                    println("sq880 <id:%d> get decTime: %.2fs", g_sq880_list[i].com.slave_id, g_sq880_list[i].accTime / 10.0f);
                }

                g_sq880_list[i].isInitOk = true;
                println("sq880 <id:%d> init success", g_sq880_list[i].com.slave_id);
            }
        }

        xp_cli_debug_add(xp_sq880_debug);
        return true;

    }else{
        return false;
    }
}
// sq880去初始化
bool xp_sq880_Deinit(void)
{
    bool ret = true;
    for (int i = 0; i < g_sq880_listLen; i++){
		if (MODE_485 == g_sq880_list[i].mode){
			if (xp_sq880_bus_run(i, 0)){
                g_sq880_list[i].isInitOk = false;
            }else{
                ret = false;
            }
		}else{
			if(xp_sq880_io_run(i, 0)){
                g_sq880_list[i].isInitOk = false;
            }else{
                ret = false;
            }
		}
    }
    return ret;
}
// sq880 读取当前模式
bool _xp_sq880_update_mode(Type_sq880_Def * const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_RUN_MODE, 1, handle->com.rec_data, &handle->com.rec_len);
	if (0 == ret){
		handle->mode = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
	}
    return false;
}
// sq880 设置命令模式
bool _xp_sq880_set_mode(Type_sq880_Def * const handle, Type_sq880_Mode_Enum val)
{
    uint16_t date = val;
    int ret = xp_sq880_write_reginster(handle, ADDR_RUN_MODE, &date, 1);
	if (0 == ret){
        handle->mode = val;
        return true;
	}
    return false;
}
// sq880 读取A频率源
bool _xp_sq880_update_A_src(Type_sq880_Def * const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_A_FREQ_SRC, 1, handle->com.rec_data, &handle->com.rec_len);
	if (0 == ret){
		handle->A_src = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
	}
    return false;
}
// sq880 设置A频率源
bool _xp_sq880_set_A_src(Type_sq880_Def * const handle, Type_sq880_A_Src_Enum val)
{
    uint16_t date = val;
    int ret = xp_sq880_write_reginster(handle, ADDR_A_FREQ_SRC, &date, 1);
	if (0 == ret){
        handle->A_src = val;
        return true;
	}
    return false;
}
// sq880 设置目标频率
bool _xp_sq880_set_tar_freq(Type_sq880_Def * const handle, uint16_t val)
{
    uint16_t date = val;
    int ret = xp_sq880_write_reginster(handle, ADDR_TAR_FREQ, &date, 1);
	if (0 == ret){
        handle->tar_freq = val;
        return true;
	}
    return false;
}
// sq880 设置控制寄存器
bool _xp_sq880_set_ctrl_reg(Type_sq880_Def * const handle, Type_sq880_Ctrl_Enum val)
{
    uint16_t date = val;
    int ret = xp_sq880_write_reginster(handle, ADDR_TAR_FREQ, &date, 1);
	if (0 == ret){
        handle->ctrl = val;
        return true;
	}
    return false;
}
// sq880 更新加速时间
bool _xp_sq880_update_acc_time(Type_sq880_Def* const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_ACC_TIME, 1, handle->com.rec_data, &handle->com.rec_len);
    if (0 == ret) {
        handle->accTime = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
    }
    return false;
}
// sq880 设置加速时间
bool _xp_sq880_set_acc_time(Type_sq880_Def* const handle, uint16_t val)
{
    uint16_t date = val;
    int ret = xp_sq880_write_reginster(handle, ADDR_ACC_TIME, &date, 1);
    if (0 == ret) {
        handle->accTime = val;
        return true;
    }
    return false;
}
// sq880 更新减速时间
bool _xp_sq880_update_dec_time(Type_sq880_Def* const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_DEC_TIME, 1, handle->com.rec_data, &handle->com.rec_len);
    if (0 == ret) {
        handle->decTime = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
    }
    return false;
}
// sq880 设置减速时间
bool _xp_sq880_set_dec_time(Type_sq880_Def* const handle, uint16_t val)
{
    uint16_t date = val;
    int ret = xp_sq880_write_reginster(handle, ADDR_DEC_TIME, &date, 1);
    if (0 == ret) {
        handle->decTime = val;
        return true;
    }
    return false;
}
// sq880 读取电流
bool _xp_sq880_update_current(Type_sq880_Def * const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_CURRENT, 1, handle->com.rec_data, &handle->com.rec_len);
	if (0 == ret){
		handle->current = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
	}
    return false;
}
// sq880 读取状态
bool _xp_sq880_update_state(Type_sq880_Def * const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_STATE, 1, handle->com.rec_data, &handle->com.rec_len);
	if (0 == ret){
		handle->state = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
	}
    return false;
}
// sq880 读取错误码
bool _xp_sq880_update_error_code(Type_sq880_Def * const handle)
{
    int ret = xp_sq880_read_reginster(handle, ADDR_ERROR_CODE, 1, handle->com.rec_data, &handle->com.rec_len);
	if (0 == ret){
		handle->errCode = (handle->com.rec_data[0] << 8) | handle->com.rec_data[1];
        return true;
	}
    return false;
}
// sq880 设置端子默认功能
bool _xp_sq880_set_io_default_function(Type_sq880_Def * const handle)
{
    uint16_t val = DI_FUN_FWD;
    int ret = xp_sq880_write_reginster(handle, ADDR_DI_S1_FUN, &val, 1);
	if (0 != ret) { return false; }
    
    val = DI_FUN_REV;
    ret = xp_sq880_write_reginster(handle, ADDR_DI_S2_FUN, &val, 1);
	if (0 != ret) { return false; }

    val = DI_FUN_STAGE_1;
    ret = xp_sq880_write_reginster(handle, ADDR_DI_S3_FUN, &val, 1);
	if (0 != ret) { return false; }

    val = DI_FUN_STAGE_2;
    ret = xp_sq880_write_reginster(handle, ADDR_DI_S4_FUN, &val, 1);
	if (0 != ret) { return false; }

    val = DI_FUN_STAGE_3;
    ret = xp_sq880_write_reginster(handle, ADDR_DI_S5_FUN, &val, 1);
	if (0 != ret) { return false; }

    return true;
}
// sq880 设置段速
bool _xp_sq880_set_stage_speed(Type_sq880_Def * const handle, uint8_t stage_id, uint16_t val)
{
    int ret = xp_sq880_write_reginster(handle, ADDR_STAGE_BASE + stage_id * 2, &val, 1);
	if (0 == ret){
        handle->stageTable[stage_id] = val;
        return true;
	}
    return false;
}

int xp_sq880_write_reginster(Type_sq880_Def * const handler, uint16_t addr, uint16_t *data, uint8_t len)
{
    int sta = 0;
    MB_data modbus;
    uint8_t try_times = 3;

    modbus.slave_id = handler->com.slave_id;
    modbus.mb_fun = mb_hold_w;
    modbus.start_addr = addr;
    modbus.wBuf = data;
    modbus.rwLen = len;
    modbus.resBuf = handler->com.rec_data;
    modbus.resLen = &handler->com.rec_len;
    while(try_times--){
        if( 0 == xp_modbus_ask(handler->com.port, &modbus) ) return 0;
    }

    return -1;
}

int xp_sq880_read_reginster(Type_sq880_Def * const handler, uint16_t addr, uint16_t read_len, uint8_t *rec_data, uint8_t *rec_len)
{
    int sta = 0;
    MB_data modbus;
    uint8_t try_times = 3;

    modbus.slave_id = handler->com.slave_id;
    modbus.mb_fun = mb_hold_r;
    modbus.start_addr = addr;
    modbus.rwLen = read_len;
    modbus.resBuf = rec_data;
    modbus.resLen = rec_len;
    while(try_times--){
        if( 0 == xp_modbus_ask(handler->com.port, &modbus) ) return 0;
    }
	println("sq880 read fail !!!");
    return -1;
}
//带大小端转换的memcpy  __REVSH
void memcpy_resv_word(void *des, void * const res, uint16_t size)
{
	for (uint16_t i = 0; i < size; i += sizeof(uint32_t)){
		*((uint8_t *)des + i + 0) = *((uint8_t *)res + i + 3);
		*((uint8_t *)des + i + 1) = *((uint8_t *)res + i + 2);
		*((uint8_t *)des + i + 2) = *((uint8_t *)res + i + 1);
		*((uint8_t *)des + i + 3) = *((uint8_t *)res + i + 0);
	}
}
//输出各参数
void xp_sq880_show(void)
{
    for (uint8_t i = 0 ; i < g_sq880_listLen; i++){
        bool isOK = false;
        /* 读取变频器运行模式 */
        isOK = _xp_sq880_update_mode(&g_sq880_list[i]);
        if (isOK) { 
            println("sq880 <id:%d> mode: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].mode < MODE_MAX ? (str_mode[g_sq880_list[i].mode]) : ("UNKNOW"));
        }else{
            println("sq880 <id:%d> mode update failed");
        }
        
        /* 读取变频器状态 */
        isOK = _xp_sq880_update_state(&g_sq880_list[i]);
        if (isOK) {
            println("sq880 <id:%d> state: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].state < STA_MAX ? (str_state[g_sq880_list[i].state]) : ("UNKNOW"));
        }else{
            println("sq880 <id:%d> state update failed");
        }
        
        /* 读取变频器A频率源 */
        isOK = _xp_sq880_update_A_src(&g_sq880_list[i]);
        if (isOK) {
            println("sq880 <id:%d> A_src: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].A_src < A_SRC_MAX ? (str_A_Src[g_sq880_list[i].A_src]) : ("UNKNOW"));
        }else{
            println("sq880 <id:%d> A_src update failed");
        }

        /* 读取变频器当前电流 */
        isOK = _xp_sq880_update_current(&g_sq880_list[i]);
        if (isOK) {
            println("sq880 <id:%d> current: %s", g_sq880_list[i].com.slave_id, g_sq880_list[i].current);
        }else{
            println("sq880 <id:%d> current update failed");
        }
        
        /* 读取变频器当前加速时间 */
        isOK = _xp_sq880_update_acc_time(&g_sq880_list[i]);
        if (isOK) {
            println("sq880 <id:%d> acc time: %d(%.2fs)", g_sq880_list[i].com.slave_id, g_sq880_list[i].accTime, g_sq880_list[i].accTime / 10.0f);
        }

        /* 读取变频器当前减速时间 */
        isOK = _xp_sq880_update_dec_time(&g_sq880_list[i]);
        if (isOK) {
            println("sq880 <id:%d> dec time: %d(%.2fs)", g_sq880_list[i].com.slave_id, g_sq880_list[i].decTime, g_sq880_list[i].decTime / 10.0f);
        }

        /* 读取变频器当前错误码 */
        isOK = _xp_sq880_update_error_code(&g_sq880_list[i]);
        if (isOK) {
            println("sq880 <id:%d> error_code: %04X", g_sq880_list[i].com.slave_id, g_sq880_list[i].errCode);
        }else{
            println("sq880 <id:%d> error_code update failed");
        }
    }
}



//外部接口
/********************************************************************************************/
// IO输出底层接口
void xp_sq880_write_pin(const uint8_t board_id,const uint8_t pin,const bool isEnable)
{
    if (IS_VALID_PIN(board_id)){    //通过板ID是否为0验证此IO是否实际使用(板ID从1开始)
        xp_io_write_pin(board_id, pin, isEnable ? (0) : (1));
    }
}
// 通过变频器索引ID获取电流
bool xp_sq880_get_current(int devId, int16_t *pResult)
{
    if (IS_SQ880_CHECK_OK(devId) && pResult){
        if (_xp_sq880_update_current(&g_sq880_list[devId])){
            *pResult = g_sq880_list[devId].current;
            return true;
        }else{
            return false;
        }
    }
    return false;
}
// 通过变频器索引ID获取错误码
bool xp_sq880_get_error_code(int devId, uint32_t *pResult)
{
    if (IS_SQ880_CHECK_OK(devId) && pResult){
        if (_xp_sq880_update_error_code(&g_sq880_list[devId])){
            *pResult = g_sq880_list[devId].errCode;
            return true;
        }else{
            return false;
        }
    }
    return false;
}
// 通过变频器索引ID获取状态
bool xp_sq880_get_state(int devId, uint16_t *pResult)
{
    if (IS_SQ880_CHECK_OK(devId) && pResult){
        if (_xp_sq880_update_state(&g_sq880_list[devId])){
            *pResult = g_sq880_list[devId].state;
            return true;
        }else{
            return false;
        }
    }
    return false;
}
// 通过变频器索引ID使用总线运转变频器
bool xp_sq880_bus_run(int devId, int freq)
{
    if (IS_SQ880_CHECK_OK(devId)){
        bool ret = false;

        if (g_sq880_list[devId].isReverseDir){
            freq = -freq;
        }

        if (MODE_485 != g_sq880_list[devId].mode){
            ret = _xp_sq880_set_mode(&g_sq880_list[devId], MODE_485);
            if (!ret)   { return false; }
        }

        if (A_SRC_MODBUS != g_sq880_list[devId].A_src){
            ret = _xp_sq880_set_A_src(&g_sq880_list[devId], A_SRC_MODBUS);
            if (!ret)   { return false; }
        }

        if (0 == freq){
            ret = _xp_sq880_set_ctrl_reg(&g_sq880_list[devId], CTRL_SLOW_STOP);
        }else{
            ret = _xp_sq880_set_tar_freq(&g_sq880_list[devId], (freq < 0) ? (-freq) : (freq));
            if (!ret)   { return false; }

            ret = _xp_sq880_set_ctrl_reg(&g_sq880_list[devId], (freq < 0) ? (CTRL_REV) : (CTRL_FWD));
        }
        return ret;
    }
    return false;
}
// 通过变频器索引ID及段速索引ID设置相应段速值
bool xp_sq880_set_stage_speed(int devId, uint8_t stage_id, uint16_t val)
{
    if (IS_SQ880_CHECK_OK(devId) && stage_id < sizeof(g_sq880_list[devId].stageTable) / sizeof(g_sq880_list[devId].stageTable[0])){
        return _xp_sq880_set_stage_speed(&g_sq880_list[devId], stage_id, val);
    }
    return false;
}
// 通过变频器索引ID设置加速时间
bool xp_sq880_set_acc_time(int devId, uint16_t val)
{
    if (IS_SQ880_CHECK_OK(devId)) {
        return _xp_sq880_set_acc_time(&g_sq880_list[devId], val);
    }
    return false;
}
// 通过变频器索引ID设置减速时间
bool xp_sq880_set_dec_time(int devId, uint16_t val)
{
    if (IS_SQ880_CHECK_OK(devId)) {
        return _xp_sq880_set_dec_time(&g_sq880_list[devId], val);
    }
    return false;
}
// 通过变频器索引ID恢复故障
bool xp_sq880_clear_error(int devId)
{
    if (IS_SQ880_CHECK_OK(devId)){
        return _xp_sq880_set_ctrl_reg(&g_sq880_list[devId], CTRL_RECOVER);
    }
    return false;
}
// 通过变频器索引ID使用IO运转变频器
bool xp_sq880_io_run(uint8_t devId, int speed)
{
    if (IS_SQ880_CHECK_OK(devId) && _ABS((int)speed) <= 7){
        bool ret = false;

        if (g_sq880_list[devId].isReverseDir){
            speed = -speed;
        }

        if (MODE_IO != g_sq880_list[devId].mode){
            ret = _xp_sq880_set_mode(&g_sq880_list[devId], MODE_IO);
            if (!ret)   { return false; }
        }

        if (A_SRC_STAGE != g_sq880_list[devId].A_src){
            ret = _xp_sq880_set_A_src(&g_sq880_list[devId], A_SRC_STAGE);
            if (!ret)   { return false; }
        }

        if (speed > 0){         //正转, MCU输出低电平导通MOS使得外接的驱动器高电平信号短接到公共端从而作用
            xp_sq880_write_pin(g_sq880_list[devId].gpio_STF.boardId, g_sq880_list[devId].gpio_STF.pinId, false);
            xp_sq880_write_pin(g_sq880_list[devId].gpio_STR.boardId, g_sq880_list[devId].gpio_STR.pinId, true);
        }else if (speed < 0){   //反转
            xp_sq880_write_pin(g_sq880_list[devId].gpio_STF.boardId, g_sq880_list[devId].gpio_STF.pinId, true);
            xp_sq880_write_pin(g_sq880_list[devId].gpio_STR.boardId, g_sq880_list[devId].gpio_STR.pinId, false);
        }else{                  //停止 speed == 0
            xp_sq880_write_pin(g_sq880_list[devId].gpio_STF.boardId, g_sq880_list[devId].gpio_STF.pinId, false);
            xp_sq880_write_pin(g_sq880_list[devId].gpio_STR.boardId, g_sq880_list[devId].gpio_STR.pinId, false);
        }

        speed = _ABS((int)speed);
        speed = speed > 0 ? (speed - 1) : (speed);  // IO Bit: 000 代表段速0, speed = (1 ~ 8)

        xp_sq880_write_pin(g_sq880_list[devId].gpio_S0.boardId, g_sq880_list[devId].gpio_S0.pinId, (speed & 0x01) ? (false) : (false));
        xp_sq880_write_pin(g_sq880_list[devId].gpio_S1.boardId, g_sq880_list[devId].gpio_S1.pinId, (speed & 0x02) ? (false) : (false));
        xp_sq880_write_pin(g_sq880_list[devId].gpio_S2.boardId, g_sq880_list[devId].gpio_S2.pinId, (speed & 0x04) ? (false) : (false));

        return true;
    }
    return false;
}



//调试接口
/********************************************************************************************/
static int xp_sq880_debug(char *type, char *fun, char *param)
{
	int ret = -1;
	
	//本调试接口仅支持 "sq880_" 起始的命令
	if (NULL == strstr(type, "sq880_")){
		return 0;
	}else{
		type += strlen("sq880_");
	}
    //xp sq880_show  输出相关信息
	if (strcasecmp(type, "show") == 0){
		xp_sq880_show();
	}
    else if (strcasecmp(type, "io_move") == 0){
		println("Use io move %s\r\n", xp_sq880_io_run(atoi(fun), atoi(param)) == true ? ("success") : ("failed"));
	}
    else if (strcasecmp(type, "bus_move") == 0){
		println("Use bus move %s\r\n", xp_sq880_bus_run(atoi(fun), atoi(param)) == true ? ("success") : ("failed"));
	}
    else if (strcasecmp(type, "set_acc") == 0) {
        println("set acc time %.2fs %s\r\n", atoi(param) / 10.0f, xp_sq880_set_acc_time(atoi(fun), atoi(param)) == true ? ("success") : ("failed"));
    }
    else if (strcasecmp(type, "set_dec") == 0) {
        println("set dec time %.2fs %s\r\n", atoi(param) / 10.0f, xp_sq880_set_dec_time(atoi(fun), atoi(param)) == true ? ("success") : ("failed"));
    }
    else {
        return 0;
    }
    return 1;
}